﻿using IPTools.Core;
using Microsoft.AspNetCore.Http;
using RxxAdmin.Common.Extensions;
using RxxAdmin.Common.Helper;
using RxxAdmin.IServices;
using RxxAdmin.Model.Entity;
using RxxAdmin.Model.Logs;
using RxxAdmin.Model.ViewModels;
using RxxAdmin.Repository;
using SqlSugar;
using System.Data;
using UAParser;

namespace RxxAdmin.Services;

public class SysUserService : BaseServices<SysUser>, ISysUserService
{
    private readonly IBaseRepository<SysUserRole> _userRoleRepository;
    private readonly IBaseRepository<SysRole> _roleRepository;
    private readonly IBaseRepository<SysMenu> _menuRepository;
    private readonly IBaseRepository<SysRoleMenu> _roleMenuRepository;
    public SysUserService(IBaseRepository<SysUserRole> userRoleRepository, 
        IBaseRepository<SysRole> roleRepository,
        IBaseRepository<SysMenu> menuRepository,
        IBaseRepository<SysRoleMenu> roleMenuRepository)
    {
        _userRoleRepository = userRoleRepository;
        _roleRepository = roleRepository;
        _menuRepository = menuRepository;
        _roleMenuRepository = roleMenuRepository;
    }    
    /// <summary>
    /// 根据Id获取用户信息
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    /// <exception cref="Exception"></exception>
    public async Task<SysUser> GetUserInfo(long id)
    {
        var user = await base.Query(d => d.Id == id);
        if (user.Count > 0)
        {
            return user[0];
        }
        else
        {
            throw new Exception("用户名或密码错误！");
        }
    }
    public async Task<string> GetUserRoleNameStr(string loginName, string loginPwd)
    {
        string roleName = "";
        var user = (await base.Query(a => a.LoginName == loginName && a.LoginPWD == loginPwd)).FirstOrDefault();
        var roleList = await _roleRepository.Query();
        if (user != null)
        {
            var userRoles = await _userRoleRepository.Query(ur => ur.UserId == user.Id);
            if (userRoles.Count > 0)
            {
                var arr = userRoles.Select(ur => ur.RoleId.ObjToString()).ToList();
                var roles = roleList.Where(d => arr.Contains(d.Id.ObjToString()));

                roleName = string.Join(',', roles.Select(r => r.Code).ToArray());
            }
        }
        return roleName;
    }

    public async Task<SysUserMenuOut> GetUserMenu(long id)
    {
        var Out = new SysUserMenuOut();
        //获取所有的菜单权限
        var menusall = await _menuRepository.Query();
        var menusroot = (await _menuRepository.Query()).Where(d=> d.ParentId == 0).OrderBy(d=>d.MenuSort).ToList();
        foreach (var item in menusroot)
        {
            var childs = menusall.Where(d => d.ParentId == item.Id);
            if (childs.Count() > 0)
            {
                item.Children = childs.ToList();
            }
        }

        List<SysMenu> menus = new List<SysMenu>();
        //获取当前用户的菜单权限
        var roleIds = (await _userRoleRepository.Query(d => d.UserId == id)).Select(d => d.RoleId.ObjToLong()).Distinct().ToList();
        if (roleIds.IndexOf(1) == -1)
        {
            var menuids = (await _roleMenuRepository.Query(d => roleIds.Contains(d.RoleId))).Select(d => d.MenuId).Distinct().ToList();
            menus = ConvertMenu(menuids, menusroot);
        }
        else {
            menus = menusroot;
        }  

        var res = new List<UserMenu>();
        foreach (var item in menus)
        {
            res.Add(ConvertMenu(item));
        }
        Out.Home = res.FirstOrDefault()?.Name;
        Out.Routes = res;

        return Out;
    }
    private List<SysMenu> ConvertMenu(List<int> menuids, List<SysMenu> menusroot)
    {
        for (int i = 0; i < menusroot.Count; i++)
        {
            if (!menuids.Contains(menusroot[i].Id))
            {
                menusroot[i].Id = 0;
            }
            if (menuids.Contains(menusroot[i].Id) && menusroot[i].Children != null)
            {
                ConvertMenu(menuids, menusroot[i].Children);
            }
        }
        return menusroot;
    }
    /// <summary>
    /// 私有方法，转化前端路由
    /// </summary>
    /// <param name="menu"></param>
    /// <returns></returns>
    private UserMenu ConvertMenu(SysMenu menu)
    {
        return menu.Id == 0 ? null : new UserMenu
        {
            Id = menu.Id,
            ParentId = menu.ParentId,
            Name = menu.RouteName,
            Path = menu.RoutePath,
            Component = menu.RoutePath + "/index",
            Status = menu.Status,
            Meta = new Meta
            {
                Title = menu.MenuTitle,
                Icon = menu.MenuIcon,
                Type = menu.MenuType,
                Sort = menu.MenuSort,
            },
            Children = menu.Children?.Select(ConvertMenu).ToList()
        };
    }    
}
